package com.sc.admin.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sc.admin.common.constant.StringPools;
import com.sc.admin.common.result.ResultCodeEnum;
import com.sc.admin.common.util.AddressUtils;
import com.sc.admin.common.util.IpUtils;
import com.sc.admin.common.util.ObjUtils;
import com.sc.admin.common.util.ServletUtils;
import com.sc.admin.converter.LoginInfoLogConverter;
import com.sc.admin.mapper.sys.SysLoginInfoMapper;
import com.sc.admin.model.entity.sys.SysLoginInfo;
import com.sc.admin.model.query.SysLoginInfoLogQuery;
import com.sc.admin.model.vo.SysLoginInfoExportVO;
import com.sc.admin.model.vo.SysLoginInfoVO;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 *@Author shen chen
 *@Date 2024-04-02
 */
@Service
@RequiredArgsConstructor
public class SysLoginInfoService extends ServiceImpl<SysLoginInfoMapper, SysLoginInfo> {

    private final SysLoginInfoMapper loginInfoMapper;
    private final LoginInfoLogConverter converter;


    public void asyncRecordLoginInfo(final String username, final ResultCodeEnum codeEnum,
                                     final Object... args) {

        // 封装对象
        final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
        final String ip = IpUtils.getIpAddr();
        SysLoginInfo loginInfo = new SysLoginInfo()
                .setLoginName(username)
                .setIpaddr(ip)
                .setLoginLocation(AddressUtils.getRealAddressByIP(ip))
                .setBrowser(userAgent.getBrowser().getName())
                .setOs(userAgent.getOperatingSystem().getName())
                .setMsg(codeEnum.getMsg())
                .setLoginTime(LocalDateTime.now());
        // 日志状态
        if (ObjUtils.anyEquals(codeEnum, ResultCodeEnum.LOGIN_SUCCESS, ResultCodeEnum.LOGIN_LOGOUT, ResultCodeEnum.REGISTER)) {
            loginInfo.setStatus(StringPools.SUCCESS_ZERO);
        } else {
            loginInfo.setStatus(StringPools.ERROR_ZERO);
        }
        // 插入数据
        loginInfoMapper.insert(loginInfo);
    }

    public IPage<SysLoginInfoVO> pageLog(SysLoginInfoLogQuery query) {

        LambdaQueryWrapper<SysLoginInfo> wrapper = getWrapper(query);

        Page<SysLoginInfo> page = page(new Page<>(query.getPageNum(), query.getPageSize()), wrapper);
        return converter.toPageVO(page);
    }

    private LambdaQueryWrapper<SysLoginInfo> getWrapper(SysLoginInfoLogQuery query) {
        return new LambdaQueryWrapper<SysLoginInfo>()
                .eq(!ObjectUtils.isEmpty(query.getStatus()), SysLoginInfo::getStatus, query.getStatus())
                .like(StringUtils.isNotBlank(query.getLoginName()), SysLoginInfo::getLoginName, query.getLoginName())
                .like(StringUtils.isNotBlank(query.getIpaddr()), SysLoginInfo::getIpaddr, query.getIpaddr())
                .ge(!ObjectUtils.isEmpty(query.getBeginTime()), SysLoginInfo::getLoginTime, query.getBeginTime())
                .le(!ObjectUtils.isEmpty(query.getEndTime()), SysLoginInfo::getLoginTime, query.getEndTime())
                .orderByDesc(SysLoginInfo::getLoginTime);
    }

    public List<SysLoginInfoExportVO> listExportLogs(SysLoginInfoLogQuery queryParams) {
        return list(getWrapper(queryParams)).stream()
                .map(obj -> converter.toExportVO(obj).setStatus(ObjUtils.equals(obj.getStatus(), 0) ? StringPools.SUCCESS_ZH : StringPools.ERROR_ZH))
                .collect(Collectors.toList());
    }
}
